/*
 * @(#)ConfigBuilderTestCase.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.parser;

import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.Properties;

import junit.framework.Assert;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.nhncorp.lucy.common.util.ResourceLoader;
import com.nhncorp.usf.core.config.runtime.Action;
import com.nhncorp.usf.core.config.runtime.BusinessObject;
import com.nhncorp.usf.core.config.runtime.BusinessObjectGroup;
import com.nhncorp.usf.core.config.runtime.ConditionInfo;
import com.nhncorp.usf.core.config.runtime.Method;
import com.nhncorp.usf.core.config.runtime.PageInfo;
import com.nhncorp.usf.core.config.runtime.ParameterInfo;
import com.nhncorp.usf.core.config.runtime.PermissionInfo;
import com.nhncorp.usf.core.config.runtime.ResultCondition;
import com.nhncorp.usf.core.config.runtime.ResultPageInfo;
import com.nhncorp.usf.core.config.runtime.ResultPageInfos;
import com.nhncorp.usf.core.config.runtime.ScriptInfo;
import com.nhncorp.usf.core.config.runtime.Service;
import com.nhncorp.usf.core.config.runtime.ServiceCondition;
import com.nhncorp.usf.core.service.ServiceType;
import com.nhncorp.usf.core.util.StringUtil;

/**
 * {@link ConfigBuilder} TestCase.
 *
 * @author Web Platform Development Team
 */
public class ConfigBuilderTestCase {
    static PageInfo pageInfo;
    static PageInfo pageInfo2;

    @BeforeClass
    public static void initialize() throws Exception {
        //AttributeInfo.getInstance().addAttribute("schemaVersion", "2.1");
        ResourceLoader loader = new ResourceLoader();
        ConfigBuilder configBuilder = new ConfigDOMBuilder();

        String RESOURCE = "runtimeconfig/example_run.xml";
        File resourceFile = loader.getFile(RESOURCE);
        String templateDir = resourceFile.toURI().getPath();
        String osName = System.getProperty("os.name").toLowerCase(Locale.US);
        if (osName.startsWith("window")) {
            templateDir = StringUtil.substringBefore(templateDir, RESOURCE).substring(1);
        } else {
            templateDir = StringUtil.substringBefore(templateDir, RESOURCE);
        }
        pageInfo = configBuilder.build(loader.getResourceAsStream(RESOURCE), templateDir);
    }

    @AfterClass
    public static void destory() throws Exception {
    }

    @Test
    public void getGlobalPermission() throws Exception {
        Assert.assertEquals("login", pageInfo.getGlobalPermission());
    }

    @Test
    public void getInclude() throws Exception {
        Assert.assertEquals("/runtimeconfig/parent", pageInfo.getInclude());
    }

    @Test
    public void getGlobalSuccessResultInfo() throws Exception {
        ResultPageInfos resultPageInfos = pageInfo.getGlobalSuccessResultInfo();

        // condition
        Assert.assertEquals(resultPageInfos.getConditions().size(), 6);
        List<ResultCondition> conditionInfos = resultPageInfos.getConditions();
        ConditionInfo conditionInfo = (ConditionInfo) conditionInfos.get(0);
        Assert.assertNotNull(conditionInfo);
        Assert.assertEquals(conditionInfo.getCodition(), "getPageNum == \"1\"");
        Assert.assertEquals(conditionInfo.getResultPageInfo().getDispatcherType().name(), "template");
        Properties properties = conditionInfo.getResultPageInfo().getProperties();
        Assert.assertNotNull(properties);
        Assert.assertEquals(properties.getProperty("language"), "freemarker");
        Assert.assertEquals(properties.getProperty("src"), "/WEB-INF/templates/condition/SuccessPage1.ftl");
        Properties staticParams = conditionInfo.getResultPageInfo().getRequestParams();
        Assert.assertNotNull(staticParams);
        Assert.assertEquals(staticParams.getProperty("message"), "this is test message.");

        // default-result
        ResultPageInfo resultPageInfo = resultPageInfos.getDefaultResultPageInfo();
        Assert.assertNotNull(resultPageInfo);
        Assert.assertEquals(resultPageInfo.getDispatcherType().name(), "template");
        properties = resultPageInfo.getProperties();
        Assert.assertNotNull(properties);
        Assert.assertEquals(properties.getProperty("language"), "freemarker");
        Assert.assertEquals(properties.getProperty("encoding"), "utf-8");
        Assert.assertEquals(properties.getProperty("src"), "/WEB-INF/templates/condition/UndefinedPage.ftl");
    }

    @Test
    public void getGlobalFailureResultInfo() throws Exception {
        ResultPageInfos resultPageInfos = pageInfo.getGlobalFailureResultInfo();
        Assert.assertEquals(3, resultPageInfos.getConditions().size());

        // default-result
        ResultPageInfo resultPageInfo = resultPageInfos.getDefaultResultPageInfo();
        Assert.assertNotNull(resultPageInfo);
        Assert.assertEquals(resultPageInfo.getDispatcherType().name(), "template");
        Assert.assertEquals(resultPageInfo.getSrc(), "/WEB-INF/templates/condition/FailurePage.ftl");
    }

    @Test
    public void getActionInfo() throws Exception {
        Action actionInfo = pageInfo.getActionInfo("init");
        Assert.assertNotNull(actionInfo);

        // permission
        PermissionInfo permissionInfo = actionInfo.getPermission();
        Assert.assertNotNull(permissionInfo);
        Assert.assertEquals("override", permissionInfo.getType());
        Assert.assertEquals("over19", permissionInfo.getRequired());

        // success/failure page
        Assert.assertNull(actionInfo.getSuccessResultInfo());
        ResultPageInfos failurePageInfos = actionInfo.getFailureResultInfo();
        Assert.assertNotNull(failurePageInfos);

        // default-result
        ResultPageInfo resultPageInfo = failurePageInfos.getDefaultResultPageInfo();
        Assert.assertNotNull(resultPageInfo);
        Assert.assertEquals(resultPageInfo.getDispatcherType().name(), "template");
        Assert.assertEquals(resultPageInfo.getSrc(), "/WEB-INF/templates/condition/FailurePage.ftl");
    }

    @SuppressWarnings("deprecation")
	@Test
    public void asyncBoTest() throws Exception {
        Action actionInfo = pageInfo.getActionInfo("init");
        Assert.assertNotNull(actionInfo);

        Service bogroup = actionInfo.getBusinessObjectInfos().get(0);
        Assert.assertEquals(ServiceType.bo_group, bogroup.getServiceType());

        BusinessObjectGroup group_0 = (BusinessObjectGroup)bogroup;
        Assert.assertEquals("javascript", group_0.getScriptInfo().getScriptType());
        Assert.assertEquals("getBOList", group_0.getScriptInfo().getFunctionName());
        Assert.assertEquals(2, group_0.getBoInfos().size());

        List<Service> serviceables = actionInfo.getBusinessObjectInfos();
        Assert.assertEquals(2, serviceables.size());
        BusinessObject bo_0 = (BusinessObject)serviceables.get(1);
        Assert.assertEquals("com.nhncorp.usf.core.service.mock.MockConditionBO", bo_0.getId());

        List<Service> bo_0_methods = bo_0.getServiceInfos();
        Assert.assertEquals(2, bo_0_methods.size());

        Method bo_0_method_0 = (Method)bo_0_methods.get(0);
        Assert.assertEquals("getPageNum", bo_0_method_0.getName());
        Assert.assertEquals("pageInfo", bo_0_method_0.getReturnId());

        List<ParameterInfo> paramIunfos = bo_0_method_0.getParameterInfos();
        Assert.assertEquals(1, paramIunfos.size());
        ParameterInfo paramInfo = paramIunfos.get(0);
        Assert.assertEquals("pagenum", paramInfo.getId());
        Assert.assertEquals("pagenum", paramInfo.getRef());
        Assert.assertEquals("1", paramInfo.getDefaultValue());
    }

    /**
     * <control>
     * <bo id="" />
     * </control>
     * 위와같은 형태를 테스트 한다
     */
    @Test
    public void controlInBoTest() {
        Action actionInfo = pageInfo.getActionInfo("init");
        List<Service> serviceables = actionInfo.getControlBlockInfos();
        Assert.assertEquals(2, serviceables.size());
        BusinessObject bo = (BusinessObject)serviceables.get(0);

        // 포함된 bo 또는 if의 갯수
        List<Service> services = bo.getServiceInfos();
        Assert.assertEquals(2, services.size());
        
        Assert.assertEquals("com.nhncorp.usf.core.service.mock.MockMyUccBO", bo.getId());

        // bo 검사
        Method method = (Method)services.get(0);
        Assert.assertEquals("getUser", method.getName());
        Assert.assertEquals("user", method.getReturnId());
        
        ServiceCondition if_condition= (ServiceCondition)services.get(1);
        Assert.assertEquals("user.flag == \"2\"", if_condition.getCondition());

        List<Service> innerMethods = if_condition.getServiceInfos();
        Assert.assertEquals(2, innerMethods.size());
        
        // 세번째 serviceable은 조건블럭이며, 두개의 bo가 존재한다.
        ServiceCondition conditionBlockOfBO = (ServiceCondition)serviceables.get(1);
        Assert.assertEquals("user.flag == \"2\"", conditionBlockOfBO.getCondition());

        List<Service> conditionalBOs = conditionBlockOfBO.getServiceInfos();
        Assert.assertEquals(2, conditionalBOs.size());
    }

    @SuppressWarnings("unchecked")
	@Test
    public void getServiceInfo() throws Exception {
        Action actionInfo = pageInfo.getActionInfo("init");
        Assert.assertNotNull(actionInfo);

        // ServiceInfo
        List<Service> serviceInfos = actionInfo.getBusinessObjectInfos();
        for (Service rootServiceInfo : serviceInfos) {
            if (!rootServiceInfo.isControlBlock() && rootServiceInfo instanceof BusinessObject) {
                BusinessObject boInfo = (BusinessObject)rootServiceInfo;
                if (boInfo.getId().equals("com.nhncorp.usf.core.service.mock.MockConditionBO")) {
                    for (Service e : boInfo.getServiceInfos()) {
                        Method methodInfo = (Method)e;
                        if (methodInfo.getName().equals("getPageNum")) {
                            List scriptInfos = methodInfo.getPreScriptList();
                            Assert.assertEquals(1, scriptInfos.size());
                            ScriptInfo scriptInfo = (ScriptInfo)scriptInfos.get(0);
                            Assert.assertNotNull(scriptInfo);
                            Assert.assertEquals("javascript", scriptInfo.getScriptType());
                            Assert.assertEquals("testMethod_7", scriptInfo.getFunctionName());
                            Assert.assertEquals("prescript", scriptInfo.getCallType());
                        }
                        if (methodInfo.getName().equals("getBook")) {
                            List scriptInfos = methodInfo.getPostScriptList();
                            Assert.assertEquals(1, scriptInfos.size());
                            ScriptInfo scriptInfo = (ScriptInfo)scriptInfos.get(0);
                            Assert.assertNotNull(scriptInfo);
                            Assert.assertEquals("groovy", scriptInfo.getScriptType());
                            Assert.assertEquals("returnMap", scriptInfo.getFunctionName());
                            Assert.assertEquals("postscript", scriptInfo.getCallType());
                        }
                    }
                }
            }
        }
    }

    @Test
    public void interceptorInfoTest() {

    }
}
